package test

import (
	"time"

	"hundsun.com/hsl/hschain/common/keystore"

	"hundsun.com/hsl/hschain/common/crypto"
	"hundsun.com/hsl/hschain/protos/common"
	pbledger "hundsun.com/hsl/hschain/protos/ledger"
)

// GenerateRandomTxs 批量生成随机交易
func GenerateRandomTxs(size uint64) []*pbledger.Transaction {
	var txs []*pbledger.Transaction
	for {
		tx := &pbledger.Transaction{
			From: "from.chain.cache.test",
			To:   "to.chain.cache.test",
			ContractId: &common.ContractIdentifier{
				Name:    "chain_cache_test",
				Version: "1.0.0",
			},
			Value:      uint64(time.Now().Unix()),
			Fee:        size,
			Payload:    nil,
			Nonce:      size,
			Signature:  nil,
			CreateTime: time.Now().UnixNano() / 1000000,
		}

		txs = append(txs, tx)
		size--
		if size == 0 {
			break
		}
	}
	return txs
}

// GenerateBlock 生成指定高度区块
func GenerateBlock(height uint64) *pbledger.Block {
	blockCreatorKeyPair, _ := crypto.KeyPairGen()
	blkHeight := height

	txs := GenerateRandomTxs(10)
	blk := &pbledger.Block{
		Header: &pbledger.BlockHeader{
			ParentHash:            []byte("0x000000000000000000000000000000"),
			Number:                blkHeight,
			Difficulty:            10000000,
			BlockTime:             time.Now().UnixNano() / int64(time.Millisecond),
			TxRootHash:            txs[0].Hash(),
			CheckBlock:            blkHeight - 1,
			BlockSequence:         blkHeight,
			Consensus:             []byte("solo"),
			ChainId:               "main",
			StateHashOfCheckBlock: []byte("0x000000000000000000000000000000"),
		},
		Transactions: txs,
	}
	blk.Sign(blockCreatorKeyPair)

	return blk
}

// GenerateBlockByAccount 指定账户生成指定高度区块
func GenerateBlockByAccount(height uint64, account keystore.Account) *pbledger.Block {
	blkHeight := height

	txs := GenerateRandomTxs(10)
	blk := &pbledger.Block{
		Header: &pbledger.BlockHeader{
			ParentHash:            []byte("0x000000000000000000000000000000"),
			Number:                blkHeight,
			Difficulty:            10000000,
			BlockTime:             time.Now().UnixNano() / int64(time.Millisecond),
			TxRootHash:            txs[0].Hash(),
			CheckBlock:            blkHeight - 1,
			BlockSequence:         blkHeight,
			Consensus:             nil,
			ChainId:               "main",
			StateHashOfCheckBlock: []byte("0x000000000000000000000000000000"),
		},
		Transactions: txs,
	}
	blk.Sign(account.GetKeyPair())

	return blk
}

// GenerateExecutedBlock 生成指定高度执行后区块
func GenerateExecutedBlock(height uint64) *pbledger.ExecutedBlock {
	blk := GenerateBlock(height)

	blkExecResult := &pbledger.BlockExecResult{
		BlockNumber:            height,
		TransactionExecResults: nil,
		StateHash:              nil,
	}
	executedBlk := &pbledger.ExecutedBlock{
		Block:           blk,
		BlockExecResult: blkExecResult,
	}
	return executedBlk
}
